package GUILayer;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

import ControlLayer.SalesCtr;
import ModelLayer.RealException;
import ModelLayer.Sale;
import ModelLayer.SalesLine;
import ModelLayer.SalesRecords;
import ModelLayer.Status;

public class OrderUI extends JPanel {

	/**
	 * Create the panel.
	 */
	private static final long serialVersionUID = 1L;

	private JPanel orderPanel;
	private JPanel showOrderPanel;
	private JPanel showAllOrdersPanel;

	private JButton btnSearchOrder;

	private JLabel lblOrderIdOrderInfo = new JLabel("Order Id:");
	private JLabel lblCustomerId = new JLabel("Customer Id:");
	private JLabel lblEmployeeId = new JLabel("Employee Id:");
	private JLabel lblDate = new JLabel("Date");
	private JLabel lblDeliveryAddress = new JLabel("Delivery Address:");
	private JLabel lblPickup = new JLabel("Self Pick Up:");
	private JLabel lblPaidStatus = new JLabel("Paid Status: ");
	private JPanel showOrderLeftPanel;
	private JPanel showOrderRightPanel;
	private JPanel orderInfoPanel;
	private JPanel orderChoicePanel;

	private JTextField textField_orderIdMenu;
	private JTextField textField_paidStatus;
	private JTextField textField_orderIdOrderInfo;
	private JTextField textField_customerId;
	private JTextField textField_employeeId;
	private JTextField textField_date;
	private JTextField textField_deliveryAddress;

	private JRadioButton rbnPickupYes = new JRadioButton("Yes");
	private JRadioButton rbnPickupNo = new JRadioButton("No");

	private ButtonGroup bgPickup = new ButtonGroup();

	private JTable showAllOrdersTable;
	private JTable showSalelineTable;

	private DefaultTableModel orderTableModel;
	private DefaultTableModel saleLineTableModel;

	private JScrollPane orderTableScrollPane;

	private SalesCtr saleCtr;

	private String loggedInPosition;

	private JButton btnConfirmPayment;

	public OrderUI() {
		saleCtr = new SalesCtr();
		initialize();
	}

	public void initialize() {

		loggedInPosition = LoginUI.getLoggedInPosition();

		this.setLayout(new BorderLayout());

		// make order top menu with search function
		JPanel orderMenuPanel = new JPanel();
		orderMenuPanel.setLayout(new BorderLayout());
		orderMenuPanel
				.setBorder(BorderFactory.createTitledBorder("Order Menu"));
		this.add(orderMenuPanel, BorderLayout.NORTH);

		JLabel lblOrderIdMenu = new JLabel("Order Id:");
		textField_orderIdMenu = new JTextField();
		textField_orderIdMenu.setColumns(8);
		btnSearchOrder = new JButton("Search");
		btnSearchOrder.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				if (showOrder(getTextFieldId(textField_orderIdMenu))) {
					textField_orderIdMenu.setText("");
				}

			}
		});

		JPanel orderMenuRightPanel = new JPanel();
		orderMenuRightPanel.setLayout(new FlowLayout());
		orderMenuPanel.add(orderMenuRightPanel, BorderLayout.EAST);

		orderMenuRightPanel.add(lblOrderIdMenu);
		orderMenuRightPanel.add(textField_orderIdMenu);
		orderMenuRightPanel.add(btnSearchOrder);

		// add panels in orderPanel card layout
		orderPanel = new JPanel();
		orderPanel.setLayout(new CardLayout());
		this.add(orderPanel, BorderLayout.CENTER);

		showAllOrdersPanel = new JPanel();
		orderPanel.add("showAllOrdersPanel", showAllOrdersPanel);
		showAllOrdersPanel.setLayout(new BoxLayout(showAllOrdersPanel,
				BoxLayout.X_AXIS));
		showAllOrdersPanel.setBorder(BorderFactory
				.createTitledBorder("All Orders"));

		// make show all orders table
		addOrderTable();

		showAllOrders();

		// make show order panel

		showOrderPanel = new JPanel();
		orderPanel.add("showOrderPanel", showOrderPanel);
		showOrderPanel.setLayout(new GridLayout(1, 2));

		showOrderLeftPanel = new JPanel();
		showOrderLeftPanel.setLayout(new BoxLayout(showOrderLeftPanel,
				BoxLayout.Y_AXIS));

		showOrderRightPanel = new JPanel();
		showOrderRightPanel.setLayout(new BoxLayout(showOrderRightPanel,
				BoxLayout.X_AXIS));
		showOrderRightPanel.setBorder(BorderFactory
				.createTitledBorder("SaleLines"));

		showOrderPanel.add(showOrderLeftPanel);
		showOrderPanel.add(showOrderRightPanel);
		addSalelineTable();

	}

	public JPanel createOrderChoicePanel() {
		JPanel orderChoicePanel = new JPanel();
		orderChoicePanel.setLayout(new FlowLayout());
		if (loggedInPosition.equals("admin")
				|| loggedInPosition.equals("salesman")) {
			JButton btnDeleteOrder = new JButton("Delete");
			btnDeleteOrder.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					deleteOrderActionPerformed(e);
				}
			});
			btnConfirmPayment = new JButton("Confirm Payment");
			btnConfirmPayment.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					confirmPaymentActionPerformed(e);
					showAllOrders();
				}
			});
			orderChoicePanel.add(btnDeleteOrder);
			orderChoicePanel.add(btnConfirmPayment);
		}
		JButton btnCancelOrder = new JButton("Cancel");
		btnCancelOrder.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cancelOrderActionPerformed(e);
			}
		});
		orderChoicePanel.add(btnCancelOrder);

		return orderChoicePanel;
	}

	public void confirmPaymentActionPerformed(ActionEvent e) {
		int orderId = Integer.parseInt(textField_orderIdOrderInfo.getText());
		try {
			saleCtr.confirmPayment(orderId);
			textField_paidStatus.setText(saleCtr.getOrder(orderId)
					.getPayStatus().toString());
		} catch (RealException e1) {

		}

	}

	public void deleteOrderActionPerformed(ActionEvent e) {

		int reply = JOptionPane.showConfirmDialog(null,
				"Are you sure you want to delete this Order ?", "Delete Order",
				JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
		if (reply == JOptionPane.YES_OPTION) {
			try {
				saleCtr.removeSales(Integer.parseInt(textField_orderIdOrderInfo
						.getText()));
			} catch (NumberFormatException e1) {

			} catch (RealException e1) {

			}
		}

		showAllOrders();
	}

	public void cancelOrderActionPerformed(ActionEvent e) {
		showAllOrders();
	}

	public JPanel createOrderInfoPanel() {
		JPanel orderInfoPanel = new JPanel();
		orderInfoPanel
				.setBorder(BorderFactory.createTitledBorder("Order Info"));
		GroupLayout gl = new GroupLayout(orderInfoPanel);
		orderInfoPanel.setLayout(gl);
		gl.setAutoCreateGaps(true);
		gl.setAutoCreateContainerGaps(true);

		textField_orderIdOrderInfo = new JTextField();
		textField_customerId = new JTextField();
		textField_employeeId = new JTextField();
		textField_date = new JTextField();
		textField_deliveryAddress = new JTextField();
		textField_paidStatus = new JTextField();

		textField_orderIdOrderInfo.setColumns(8);
		textField_customerId.setColumns(8);
		textField_employeeId.setColumns(8);
		textField_date.setColumns(8);
		textField_deliveryAddress.setColumns(8);
		textField_paidStatus.setColumns(8);

		bgPickup.add(rbnPickupYes);
		bgPickup.add(rbnPickupNo);

		gl.setHorizontalGroup(gl
				.createSequentialGroup()
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.LEADING)
								.addComponent(lblOrderIdOrderInfo)
								.addComponent(lblPaidStatus)
								.addComponent(lblCustomerId)
								.addComponent(lblEmployeeId)
								.addComponent(lblDate)
								.addComponent(lblDeliveryAddress)
								.addComponent(lblPickup))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.LEADING)
								.addComponent(textField_orderIdOrderInfo)
								.addComponent(textField_paidStatus)
								.addComponent(textField_customerId)
								.addComponent(textField_employeeId)
								.addComponent(textField_date)
								.addComponent(textField_deliveryAddress)
								.addComponent(rbnPickupYes)
								.addComponent(rbnPickupNo)));
		gl.setVerticalGroup(gl
				.createSequentialGroup()
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblOrderIdOrderInfo)
								.addComponent(textField_orderIdOrderInfo))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblPaidStatus)
								.addComponent(textField_paidStatus))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblCustomerId)
								.addComponent(textField_customerId))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblEmployeeId)
								.addComponent(textField_employeeId))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblDate)
								.addComponent(textField_date))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblDeliveryAddress)
								.addComponent(textField_deliveryAddress))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
								.addComponent(lblPickup)
								.addComponent(rbnPickupYes))
				.addGroup(
						gl.createParallelGroup(GroupLayout.Alignment.LEADING)
								.addComponent(rbnPickupNo)));

		textField_orderIdOrderInfo.setEditable(false);
		textField_paidStatus.setEditable(false);
		textField_customerId.setEditable(false);
		textField_employeeId.setEditable(false);
		textField_date.setEditable(false);
		textField_deliveryAddress.setEditable(false);
		rbnPickupYes.setEnabled(false);
		rbnPickupNo.setEnabled(false);

		return orderInfoPanel;
	}

	public void addSalelineTable() {
		saleLineTableModel = new DefaultTableModel() {
			private static final long serialVersionUID = 1L;

			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
		};
		saleLineTableModel.addColumn("Barcode");
		saleLineTableModel.addColumn("Product");
		saleLineTableModel.addColumn("Quantity");
		saleLineTableModel.addColumn("Sale Price");
		saleLineTableModel.addColumn("Tax");
		saleLineTableModel.addColumn("Subtotal Price");

		orderTableScrollPane = new JScrollPane();

		showOrderRightPanel.add(orderTableScrollPane);
		showSalelineTable = new JTable(saleLineTableModel);
		showSalelineTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
		showSalelineTable.setAutoCreateRowSorter(true);

		orderTableScrollPane.setViewportView(showSalelineTable);

	}

	public void addOrderTable() {
		orderTableModel = new DefaultTableModel() {
			private static final long serialVersionUID = 1L;

			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
		};
		orderTableModel.addColumn("ID");
		orderTableModel.addColumn("Customer");
		orderTableModel.addColumn("Group");
		orderTableModel.addColumn("Date");
		orderTableModel.addColumn("Paid Status");
		orderTableModel.addColumn("Total Price");

		orderTableScrollPane = new JScrollPane();
		showAllOrdersPanel.add(orderTableScrollPane);
		showAllOrdersTable = new JTable(orderTableModel);
		showAllOrdersTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
		showAllOrdersTable.setAutoCreateRowSorter(true);

		showAllOrdersTable.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				int row = showAllOrdersTable.rowAtPoint(e.getPoint());
				if (e.getClickCount() == 2) {
					if (showOrder(Integer.valueOf((Integer) showAllOrdersTable
							.getValueAt(row, 0)))) {
					}
				}
			}
		});
		orderTableScrollPane.setViewportView(showAllOrdersTable);
	}

	public int getTextFieldId(JTextField textField) {
		int id = 0;
		try {
			id = Integer.parseInt(textField.getText());
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(null, "Please input number", "Error",
					JOptionPane.ERROR_MESSAGE);
		} finally {
			textField.setText("");
		}
		return id;
	}

	public boolean showOrder(int orderId) {
		boolean success = true;
		Sale order = null;
		try {
			if (orderId != 0) { // orderId = 0 does not exit
				order = saleCtr.getOrder(orderId);
			}
		} catch (RealException e) {
			success = false;
			JOptionPane.showMessageDialog(null, e.getError(), "Error",
					JOptionPane.ERROR_MESSAGE);
			return success;
		}

		if (success) {
			orderInfoPanel = createOrderInfoPanel();

			showOrderLeftPanel.removeAll();
			showOrderLeftPanel.add(orderInfoPanel);
			orderChoicePanel = createOrderChoicePanel();
			showOrderLeftPanel.add(orderChoicePanel);

			textField_orderIdOrderInfo.setText(Integer.toString(order.getId()));
			textField_paidStatus.setText(order.getPayStatus().toString());
			textField_customerId.setText(Integer.toString(order.getCustomer()
					.getId()));
			textField_employeeId.setText(Integer.toString(order.getEmployee()
					.getId()));
			textField_date.setText(order.getDate());
			if (order.getPickup()) {
				rbnPickupYes.setSelected(true);
			} else {
				rbnPickupNo.setSelected(true);
				textField_deliveryAddress.setText(order.getdAddress());
			}
			
			if(order.getPayStatus() == Status.Paid)
			{
				btnConfirmPayment.setEnabled(false);
			}
			else
			{
				btnConfirmPayment.setEnabled(true);
			}

			ArrayList<SalesLine> saleLines = order.getSaleLines();
			saleLineTableModel.setRowCount(0);
			for (SalesLine saleline : saleLines) {
				saleLineTableModel.addRow(new Object[] { saleline.getBarcode(),
						saleline.getSaleItem().getName(),
						saleline.getQuantity(),
						saleline.getSaleItem().getsPrice(),
						saleline.getSaleItem().getTax(),
						saleline.getSubtotalWithoutDiscount() });
			}
			addTotalPrice(orderId, saleLineTableModel);
		}
		CardLayout cl = (CardLayout) orderPanel.getLayout();
		cl.show(orderPanel, "showOrderPanel");

		return success;
	}

	// add total price of order to table model
	public void addTotalPrice(int orderId, DefaultTableModel tableModel) {
		String totalPrice = "";

		double price = 0;
		double discount = 0;
		try {
			price = saleCtr.getOrder(orderId).getTotalPriceWithDiscount();
			discount = saleCtr.getOrder(orderId).getTotalPriceWithoutDiscount();
		} catch (RealException e) {
			JOptionPane.showMessageDialog(null, e.getError(), "Error",
					JOptionPane.ERROR_MESSAGE);
		}
		if (price != 0.0) {
			totalPrice = Double.toString(Double.valueOf(new DecimalFormat(
					"#.##").format(price)));
		} else {
			totalPrice = Double.toString(price);
		}
		String[] space = { "", "", "", "", "", "" };
		String[] discountRow = { "", "", "", "", "Discount:", Double.toString(Double.valueOf(new DecimalFormat(
				"#.##").format(price - discount)))};
		String[] totalPriceRow = { "", "", "", "", "Total Price:", totalPrice };
		tableModel.addRow(space);
		tableModel.addRow(space);
		tableModel.addRow(discountRow);
		tableModel.addRow(totalPriceRow);
	}

	public void showAllOrders() {

		ArrayList<Sale> sales = SalesRecords.getInstance().getSalesRecords();
		orderTableModel.setRowCount(0);
		for (Sale order : sales) {
			if (order.getStatus() == Status.Order) {
				try {
					orderTableModel
							.addRow(new Object[] {
									order.getId(),
									order.getCustomer().getName(),
									order.getCustomer().getGroup().getId(),
									order.getDate(),
									order.getPayStatus().toString(),
									Double.valueOf(new DecimalFormat("#.##").format(order
											.getTotalPriceWithDiscount())) });
				} catch (RealException e) {
					JOptionPane.showMessageDialog(null, e.getError(), "Error",
							JOptionPane.ERROR_MESSAGE);
				}
			}
		}
		CardLayout cl = (CardLayout) orderPanel.getLayout();
		cl.show(orderPanel, "showAllOrdersPanel");
	}

}
